package cn.lijigou.shopping.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import cn.lijigou.shopping.domain.MLocation;
import cn.lijigou.shopping.domain.MResult;
import cn.lijigou.shopping.util.GetSingleThreadPool;
import cn.lijigou.shopping.util.Util;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class LocationGps {
	private int changeSize = 0;
	private Context context = null;
	private LocationManager locationManager = null;
	private Map<String,Location>  locations = new HashMap<String,Location>();
	private MLocation mLocation = new MLocation();
	private ExecutorService executorService= GetSingleThreadPool.getInstance();

	public LocationGps() {
		super();
	}

	public LocationGps(Context a) {
		this.context = a;
	}

	public void start() {
		locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		
		Location lastLoactionGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		Location lastLoactionNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		locations.put(LocationManager.GPS_PROVIDER, lastLoactionGps);
		locations.put(LocationManager.NETWORK_PROVIDER, lastLoactionNetwork);
		
		if (locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
		}
		
		if (locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER)) {
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
		}

	}

	private LocationListener locationListener = new LocationListener() {
		
		public void onLocationChanged(Location location) {
			select(location);
		}

		
		public void onProviderDisabled(String provider) {

		}

		
		public void onProviderEnabled(String provider) {

		}

		
		public void onStatusChanged(String provider, int status, Bundle extras) {

		}
	};

	private void select(final Location location) {
		
		double distance = 0;
		final String provider = location.getProvider();
		
		if (locations.get(provider) != null) {
			distance = Util.getDistance(locations.get(provider).getLatitude(),
					locations.get(provider).getLongitude(), location
							.getLatitude(), location.getLongitude());
		}
		if (distance != 0) {
			this.stop();
			executorService.execute(new Thread() {
				public void run() {
					updateWithNewLocation(location, provider);
				}
			});
		}else{
			changeSize++;
			if (changeSize > 3) {
				this.stop();
			}
		}
	}

	private void updateWithNewLocation(final Location location_,final String from) {

				MResult mResult = MSystem.geo_offset(mLocation, location_);
				if (mResult != null && mResult.isSuccess()) {
					try {
						Geocoder ge = new Geocoder(context);
						List<Address> addList = ge.getFromLocation(mLocation.getLat(),mLocation.getLng(), 1);
						
						if (addList != null && addList.size() > 0) {
							for (int i = 0; i < addList.size(); i++) {
								Address ad = addList.get(i);
								mLocation.setAddress(ad.getAddressLine(1)
										+ ad.getAddressLine(2));
								mLocation.setCity(ad.getLocality());
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					LocationService.locations.put(from, mLocation);
					LocationService.select();
				}
	}
	public void stop() {
		try {
			locationManager.removeUpdates(locationListener);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
